package com.workflow.engine.parser.utils;

import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
import org.apache.http.HttpHost;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;

import javax.net.ssl.SSLContext;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.LinkedHashMap;
import java.util.Map;


/**
 * Created by houjinxin on 2016/12/31.
 */
public class RequestUtil {

    private static int DEFAULT_SO_TIMEOUT = 60 * 1000;
    private static int  DEFAULT_CONNECT_TIMEOUT = 60 * 1000;
    private static BasicCookieStore cookieStore = new BasicCookieStore();
    static {
//        Unirest.setProxy(new HttpHost("127.0.0.1", 8888));
        try {
            Unirest.setHttpClient(initHttpsClient());
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
    }

    /**
     * 初始化httpsclient
     * @return
     * @throws KeyStoreException
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     */
    public static CloseableHttpClient initHttpsClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
        SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
            public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                return true;
            }
        }).build();
        RequestConfig defaultRequestConfig = RequestConfig.custom()
                .setSocketTimeout(DEFAULT_CONNECT_TIMEOUT)
                .setConnectTimeout(DEFAULT_SO_TIMEOUT)
                .setCookieSpec(CookieSpecs.DEFAULT) //此处使用默认的Cookie规范，可以让后续请求共享Cookie
//                .setCookieSpec(CookieSpecs.BEST_MATCH)
//                .setCookieSpec(CookieSpecs.NETSCAPE)
//                .setCookieSpec(CookieSpecs.BROWSER_COMPATIBILITY)

//                .setCookieSpec(CookieSpecs.IGNORE_COOKIES)
//                .setCookieSpec(CookieSpecs.STANDARD)
//                .setCookieSpec(CookieSpecs.STANDARD_STRICT)
                .setRedirectsEnabled(true)
//                .setCircularRedirectsAllowed(false)
                .build();
        return HttpClients.custom()
                .setDefaultRequestConfig(defaultRequestConfig)
                .setRedirectStrategy(new LaxRedirectStrategy())
                .setSSLSocketFactory(new SSLConnectionSocketFactory(sslContext))
                .setProxy(new HttpHost("127.0.0.1", 8888))
                .setDefaultCookieStore(cookieStore)
                .build();
    }

    public static BasicCookieStore getCookieStore(){
        return cookieStore;
    }

    /**
     * 执行GET方法, 带Header与不带Header的方法
     *
     * @param url
     * @param params
     * @return
     * @throws Exception
     */
    public static InputStream getAsStream(String url, Map<String, String> params, Map<String, String> headers) throws Exception {
        HttpResponse<InputStream> response = Unirest.get(url)
                .headers(headers)
                .queryString(new LinkedHashMap<String, Object>(){{
                    putAll(params);
                }}).asBinary();
        return response.getBody();
    }

    public static String get(String url, Map<String, String> params, Map<String, String> headers) throws Exception {
        HttpResponse<String> response = Unirest.get(url)
                .headers(headers)
                .queryString(new LinkedHashMap<String, Object>(){{
                    putAll(params);
                }}).asString();
        return response.getBody();
    }

    public static String get(String url, Map<String, String> params) throws Exception {
        return get(url, params, null);
    }

    /**
     * 执行Post方法, 带Header与不带Header的方法
     *
     * @param url
     * @param params
     * @param headers
     * @return
     * @throws Exception
     */
    public static InputStream postAsStream(String url, Map<String, String> params, Map<String, String> headers) throws Exception {
        HttpResponse<InputStream> response = Unirest.post(url)
                .headers(headers)
                .queryString(new LinkedHashMap<String, Object>(){{
                    putAll(params);
                }}).asBinary();
        return response.getBody();
    }

    public static String post(String url, Map<String, String> params, Map<String, String> headers) throws Exception {
        HttpResponse<String> response = Unirest.post(url)
                .headers(headers)
                .fields(new LinkedHashMap<String, Object>(){{
                    putAll(params);
                }}).asString();
        return response.getBody();
    }

    public static String post(String url, Map<String, String> params) throws Exception {
        return post(url, params, null);
    }

}
